package com.dong.order.lb;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author DJ
 * @description 自定义的负载均衡算法
 * @date 2022/1/3 11:20 下午
 **/
@Component
@Slf4j
public class MyLb implements ILoadBalancer {

    /**
     * 记录之前的请求次数
     */
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    /**
     * 获取当前的请求计数
     *
     * @param
     * @return int
     * @author DJ
     * @date 11:22 下午 2022/1/3
     **/
    public int getAndIncrement() {
        int current;
        int next;
        do {
            current = atomicInteger.get();
            next = current > Integer.MAX_VALUE ? 0 : current + 1;
            // CAS
        } while (!this.atomicInteger.compareAndSet(current, next));
        log.info("第几次访问,次数next:{}", next);
        return next;
    }

    /**
     * rest接口第几次请求数 % 服务器集群总数 = 实际调用服务器位置下标，每次服务重启后rest接口计数从1开始
     *
     * @author DJ
     * @date 11:50 下午 2022/1/3
     * @param  instances
     * @return org.springframework.cloud.client.ServiceInstance
     **/
    @Override
    public ServiceInstance chooseInstance(List<ServiceInstance> instances) {
        if (instances == null || instances.size() <= 0) {
            // 实际的接口调用不建议返回被调用方null，如果在提醒对方判空的情况下可以这样写
            return null;
        }
        // 负载均衡算法选择服务实例
        int index = getAndIncrement() % instances.size();
        return instances.get(index);
    }
}
